package com.net.xpay.admin.controller.admin.rbac;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.common.model.ResultPagedList;
import com.net.xpay.admin.secutiry.RequestUser;
import com.net.xpay.admin.vo.AdminUserVo;
import com.net.xpay.common.domain.admin.rbac.AdminUser;
import com.net.xpay.common.domain.admin.rbac.AdminUserRole;
import com.net.xpay.common.domain.admin.rbac.Role;
import com.net.xpay.common.manager.admin.rbac.AdminUserManager;
import com.net.xpay.common.manager.admin.rbac.AdminUserRoleManager;
import com.net.xpay.common.manager.admin.rbac.RoleManager;
import com.net.xpay.common.model.PasswordModel;
import com.net.xpay.common.model.admin.rbac.search.AdminUserSearchModel;
import com.net.xpay.common.validator.admin.rbac.AdminUserValidator;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.utils.BeanCopierUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDateTime;
import java.util.List;

/**
 jie
 * @date 2018-11-23
 */
@RestController
@RequestMapping("/admin/admin-user")
@Api(tags = "运营/用户管理", description = "运营 用户管理 net")
public class AdminUserController {
    private static final int MAX_PASS_LENGTH = 20; //最大的密码长度
    private static final int MIN_PASS_LENGTH = 6; //最小的密码长度

    @Autowired
    private AdminUserManager adminUserManager;

    @Autowired
    private AdminUserValidator adminUserValidator;

    @Autowired
    private AdminUserRoleManager adminUserRoleManager;

    @Autowired
    private RoleManager roleManager;

    @ApiOperation("分页搜索用户")
    @PostMapping("/search")
    @PreAuthorize("hasAnyRole('ADMIN', 'admin-user::search')")
    public ResultPagedList<AdminUserVo> searchAdminUser(@ApiIgnore @RequestUser AdminUser adminUser, @RequestBody AdminUserSearchModel searchModel){
        searchModel.setEnabled(true);
        List<AdminUser> adminUsers = adminUserManager.search(searchModel);
        List<AdminUserVo> vos = BeanCopierUtil.batchCopy(AdminUser.class, AdminUserVo.class, adminUsers);
        if (CollectionUtils.isNotEmpty(vos)) {
            for (AdminUserVo user : vos) {
                user.setPassword(null);
                List<AdminUserRole> adminUserRoles = adminUserRoleManager.listByAdminUserId(user.getId());
                if (CollectionUtils.isEmpty(adminUserRoles)) {
                    continue;
                }
                List<String> roles = Lists.newArrayList();
                for (AdminUserRole userRole : adminUserRoles) {
                    Role role = roleManager.getById(userRole.getRoleId());
                    roles.add(role.getName());
                }
                user.setRoles(roles);
            }
        }

        long count = adminUserManager.searchCount(searchModel);
        return new ResultPagedList<>(vos, count, searchModel);
    }

    @ApiOperation("获取用户")
    @GetMapping
    public ResultData<AdminUserVo> getAdminUser(@ApiIgnore @RequestUser AdminUser adminUser){
        adminUser.setPassword(null);
        AdminUserVo vo = new AdminUserVo();
        BeanCopierUtil.copy(adminUser, vo);
        return new ResultData<>(vo);
    }

    @ApiOperation(value = "修改密码（登录后才能操作）")
    @PutMapping("/modify-password")
    public ResultData<Boolean> modifyPassword(@ApiIgnore @RequestUser AdminUser adminUser, @RequestBody PasswordModel passwordModel) {
        if (adminUser == null) {
            throw new BusinessException(PoseidonErrorCode.NEED_LOGIN, "请先登录,登陆之后才能修改密码");
        }

        if (Strings.isNullOrEmpty(passwordModel.getOldPassword())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "旧密码不能为空");
        }
        if (!BCrypt.checkpw(passwordModel.getOldPassword(), adminUser.getPassword())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "密码不正确");
        }
        if (Strings.isNullOrEmpty(passwordModel.getPassword())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "新密码不能为空");
        }
        if (Strings.isNullOrEmpty(passwordModel.getRepeatPassword())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "再次输入的新密码不能为空");
        }
        if (!passwordModel.getPassword().equals(passwordModel.getRepeatPassword())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "两次输入的新密码不一样");
        }
        if (passwordModel.getPassword().length() > MAX_PASS_LENGTH || passwordModel.getPassword().length() < MIN_PASS_LENGTH) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "密码长度必须在6到20个字符");
        }
        adminUser.setPassword(BCrypt.hashpw(passwordModel.getPassword(), BCrypt.gensalt()));
        adminUser.setLastPasswordResetTime(LocalDateTime.now());
        adminUserManager.update(adminUser);
        return new ResultData<>(true);
    }

    @ApiOperation("创建用户")
    @PostMapping
    @PreAuthorize("hasAnyRole('ADMIN','admin-user::add')")
    public ResultData<String> create(@RequestBody AdminUser adminUser){
        adminUserValidator.validateCreateAdminUser(adminUser);
        AdminUser user = new AdminUser();
        user.setUsername(adminUser.getUsername());
        user.setAvatar("https://img.zcool.cn/community/01b4aa5bc1e527a8012099c85263eb.png@1280w_1l_2o_100sh.png");
        user.setEmail("");
        user.setMobile(adminUser.getMobile());
        user.setEnabled(true);
        String psw = "admin?" + RandomUtils.nextInt(100000, 1000000) + "x@";
        user.setPassword(BCrypt.hashpw(psw, BCrypt.gensalt()));
        user.setErrorLoginCount(0L);
        user.setLastLoginTime(null);
        user.setLastLoginIp(null);
        user.setLastPasswordResetTime(LocalDateTime.now());
        adminUserManager.save(user);

        return new ResultData<>(psw);
    }

    @ApiOperation(value = "删除角色")
    @PostMapping("/remove-role")
    @PreAuthorize("hasAnyRole('ADMIN','admin-user::remove-role')")
    public ResultData<Boolean> removeRole(@ApiIgnore @RequestUser AdminUser adminUser,@RequestBody Long id) {
        if (adminUser == null) {
            throw new BusinessException(PoseidonErrorCode.NEED_LOGIN, "请先登录,登陆之后才能删除角色");
        }

        AdminUser user = adminUserManager.getById(id);
        user.setEnabled(false);
        adminUserManager.update(user);
        return new ResultData<>(true);
    }

    @ApiOperation(value = "重置密码（登录后才能操作）")
    @PostMapping("/resetting-password")
    @PreAuthorize("hasAnyRole('ADMIN','admin-user::resetting-password')")
    public ResultData<String> resettingPassword(@ApiIgnore @RequestUser AdminUser adminUser, @RequestBody Long id) {
        if (adminUser == null) {
            throw new BusinessException(PoseidonErrorCode.NEED_LOGIN, "请先登录,登陆之后才能修改密码");
        }
        AdminUser user = adminUserManager.getById(id);
        String psw = "admin?" + RandomUtils.nextInt(100000, 1000000) + "x@";
        user.setPassword(BCrypt.hashpw(psw, BCrypt.gensalt()));
        user.setLastPasswordResetTime(LocalDateTime.now());
        adminUserManager.update(user);
        return new ResultData<>(psw);
    }

}
